package com.yanqu.road.dao.impl.player;

import com.yanqu.road.dao.db.DbNameStrategy;
import com.yanqu.road.dao.db.DbParameter;
import com.yanqu.road.dao.impl.TempDataObjectDao;
import com.yanqu.road.entity.activity.cookboy.CookBoyData;
import com.yanqu.road.utils.string.StringUtils;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class UserCookBoyDaoImpl extends TempDataObjectDao<CookBoyData> {

    public boolean addUserCooBoyList(List<CookBoyData> cookBoyDataList) {
        boolean result = false;
        String sql = "insert into t_u_activity_cookboy(activityId,userId,`no`,able,integral,allIntegral,hp,hpTime," +
                "finishFoodId,finishFoodData,finishFoodCount,tableFoodData,dishId,process,dishCount,isWorship)" +
                " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CookBoyData info : cookBoyDataList) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.INTEGER, info.getActivityId()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getUserId()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getNo()));
            para.put(i++, new DbParameter(Types.BOOLEAN, info.isAble()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getIntegral()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getAllIntegral()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getHp()));
            para.put(i++, new DbParameter(Types.BIGINT, info.getHpTime()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getFinishFoodId()));
            para.put(i++, new DbParameter(Types.VARCHAR, info.getFinishFoodData()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getFinishFoodCount()));
            para.put(i++, new DbParameter(Types.VARCHAR, info.getTableFoodData()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getDishId()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getProcess()));
            para.put(i++, new DbParameter(Types.INTEGER, info.getDishCount()));
            para.put(i++, new DbParameter(Types.BOOLEAN, info.isWorship()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public boolean updateUserCooBoyList(List<CookBoyData> userCookBoyList) {
        boolean result = false;
        String sql = "UPDATE t_u_activity_cookboy SET able=?,integral=?,allIntegral=?,hp=?,hpTime=?,finishFoodId=?,finishFoodData=?,finishFoodCount=?,tableFoodData=?,dishId=?,process=?,dishCount=?,isWorship=? " +
                "where activityId=? AND userId = ? AND no = ?";
        getDb().setConnName(DbNameStrategy.getUserDb());
        List<Map<Integer, DbParameter>> mapList = new ArrayList<>();
        for (CookBoyData data : userCookBoyList) {
            Map<Integer, DbParameter> para = new HashMap<>();
            int i = 1;
            para.put(i++, new DbParameter(Types.BOOLEAN, data.isAble()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getIntegral()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getAllIntegral()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getHp()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getHpTime()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getFinishFoodId()));
            para.put(i++, new DbParameter(Types.VARCHAR, data.getFinishFoodData()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getFinishFoodCount()));
            para.put(i++, new DbParameter(Types.VARCHAR, data.getTableFoodData()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getDishId()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getProcess()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getDishCount()));
            para.put(i++, new DbParameter(Types.BOOLEAN,data.isWorship()));
            para.put(i++, new DbParameter(Types.INTEGER, data.getActivityId()));
            para.put(i++, new DbParameter(Types.BIGINT, data.getUserId()));
            para.put(i++, new DbParameter(Types.INTEGER,data.getNo()));
            mapList.add(para);
        }
        if (getDb().executeBatchQuery(sql, mapList) > -1) {
            result = true;
        }
        return result;
    }

    public Map<Long, CookBoyData> getUserCookBoyMap(int activityId) {
        Map<Long, CookBoyData> res = new ConcurrentHashMap<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "select * from t_u_activity_cookboy where activityId = ?";
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setInt(i++,activityId);
            rs = call.executeQuery();
            while (rs.next()) {
                CookBoyData data = parse(rs);
                res.put(data.getUserId(),data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return res;
    }

    public Map<Integer, CookBoyData> getUserHistoryRecoverCookBoy2Map(long userId,List<Integer> activityIdList) {
        Map<Integer, CookBoyData> res = new ConcurrentHashMap<>();
        ResultSet rs = null;
        CallableStatement call = null;
        String where = "";
        if(activityIdList.size() > 0){
            where = " AND activityId not in ("+StringUtils.listToString(activityIdList,",")+")";
        }
        String sql = "select * from t_u_activity_cookboy where userId = ? AND integral != 0 AND `no` = 2 " + where;
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setLong(i++,userId);
            rs = call.executeQuery();
            while (rs.next()) {
                CookBoyData data = parse(rs);
                res.put(data.getActivityId(),data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return res;
    }

    public Map<Integer,Map<Long, CookBoyData>> getUserCookBoyAcMap(List<Integer> activityIdList) {
        Map<Integer,Map<Long, CookBoyData>> res = new ConcurrentHashMap<>();
        if(activityIdList.size() == 0){
            return res;
        }
        ResultSet rs = null;
        CallableStatement call = null;
        String activityIdCondition = "activityId in ("+StringUtils.listToString(activityIdList,",")+")";
        String sql = "select * from t_u_activity_cookboy where " + activityIdCondition;
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            rs = call.executeQuery();
            while (rs.next()) {
                CookBoyData data = parse(rs);
                if(!res.containsKey(data.getActivityId())){
                    res.put(data.getActivityId(),new ConcurrentHashMap<>());
                }
                res.get(data.getActivityId()).put(data.getUserId(),data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return res;
    }

    public CookBoyData getUserCookBoy(int activityId,long userId) {
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "select * from t_u_activity_cookboy where activityId = ? AND userId = ?";
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareCall(sql);
            int i = 1;
            call.setInt(i++,activityId);
            call.setLong(i++,userId);
            rs = call.executeQuery();
            while (rs.next()) {
                CookBoyData data = parse(rs);
                return data;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return null;
    }


    @Override
    protected boolean addData(CookBoyData data) {
        PreparedStatement call = null;
        String sql = "insert into t_u_activity_cookboy(activityId,userId,`no`,able,integral,allIntegral,hp,hpTime," +
                "finishFoodId,finishFoodData,finishFoodCount,tableFoodData,dishId,process,dishCount,isWorship)" +
                " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareStatement(sql);
            int i = 1;
            call.setInt(i++, data.getActivityId());
            call.setLong(i++, data.getUserId());
            call.setInt(i++, data.getNo());
            call.setBoolean(i++, data.isAble());
            call.setLong(i++, data.getIntegral());
            call.setLong(i++, data.getAllIntegral());
            call.setInt(i++, data.getHp());
            call.setLong(i++, data.getHpTime());
            call.setInt(i++, data.getFinishFoodId());
            call.setString(i++, data.getFinishFoodData());
            call.setInt(i++, data.getFinishFoodCount());
            call.setString(i++, data.getTableFoodData());
            call.setInt(i++, data.getDishId());
            call.setInt(i++, data.getProcess());
            call.setInt(i++, data.getDishCount());
            call.setBoolean(i++, data.isWorship());

            return call.executeUpdate() > 0;
        } catch (Exception e) {
            logger.error(Thread.currentThread().getStackTrace()[1].getMethodName() + ":", e);
        } finally {
            getDb().closeConnection(call, null);
        }
        return false;
    }

    @Override
    protected boolean updateData(CookBoyData data) {
        PreparedStatement call = null;
        String sql = "UPDATE t_u_activity_cookboy SET able=?,integral=?,allIntegral=?,hp=?,hpTime=?,finishFoodId=?,finishFoodData=?,finishFoodCount=?,tableFoodData=?,dishId=?,process=?,dishCount=?,isWorship=? " +
                "where activityId=? AND userId = ? AND no = ?";
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareStatement(sql);
            int i = 1;
            call.setBoolean(i++, data.isAble());
            call.setLong(i++, data.getIntegral());
            call.setLong(i++, data.getAllIntegral());
            call.setInt(i++, data.getHp());
            call.setLong(i++, data.getHpTime());
            call.setInt(i++, data.getFinishFoodId());
            call.setString(i++, data.getFinishFoodData());
            call.setInt(i++, data.getFinishFoodCount());
            call.setString(i++, data.getTableFoodData());
            call.setInt(i++, data.getDishId());
            call.setInt(i++, data.getProcess());
            call.setInt(i++, data.getDishCount());
            call.setBoolean(i++, data.isWorship());
            call.setInt(i++, data.getActivityId());
            call.setLong(i++, data.getUserId());
            call.setInt(i++, data.getNo());

            return call.executeUpdate() > 0;
        } catch (Exception e) {
            logger.error(Thread.currentThread().getStackTrace()[1].getMethodName() + ":", e);
        } finally {
            getDb().closeConnection(call, null);
        }
        return false;
    }

    @Override
    protected CookBoyData parseData(ResultSet rs) throws SQLException {
        CookBoyData data = new CookBoyData();
        data.setActivityId(rs.getInt("activityId"));
        data.setUserId(rs.getLong("userId"));
        data.setNo(rs.getInt("no"));
        data.setAble(rs.getBoolean("able"));
        data.setHp(rs.getInt("hp"));
        data.setHpTime(rs.getLong("hpTime"));
        data.setIntegral(rs.getLong("integral"));
        data.setAllIntegral(rs.getLong("allIntegral"));
        data.setFinishFoodId(rs.getInt("finishFoodId"));
        data.setFinishFoodData(rs.getString("finishFoodData"));
        data.setFinishFoodCount(rs.getInt("finishFoodCount"));
        data.setTableFoodData(rs.getString("tableFoodData"));
        data.setDishId(rs.getInt("dishId"));
        data.setProcess(rs.getInt("process"));
        data.setDishCount(rs.getInt("dishCount"));
        data.setWorship(rs.getBoolean("isWorship"));
        return data;
    }

}
